import React, { useContext, useEffect, useRef, useState } from 'react';
import type { InputRef } from 'antd';
import { Form, Input, Table, Button, message, Switch } from 'antd';
import type { FormInstance } from 'antd/es/form';
import {
    PlusOutlined, DeleteOutlined
} from '@ant-design/icons';
import { deepClone } from '@/utils/index'
import { getUserMenuList, setUserMenuList, delUserMenuList, getNavigationId } from '@/request/basicSettings'
const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface Item {
    nid: React.Key;
    label?: string;
    icon?: string
    key?: string;
    children?: any[]
}

interface EditableRowProps {
    index: number;
}

const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => {
    const [form] = Form.useForm();
    return (
        <Form form={form} component={false}>
            <EditableContext.Provider value={form}>
                <tr {...props} />
            </EditableContext.Provider>
        </Form>
    );
};

interface EditableCellProps {
    title: React.ReactNode;
    editable: boolean;
    children: React.ReactNode;
    dataIndex: keyof Item;
    record: Item;
    handleSave: (record: Item) => void;
}


type EditableTableProps = Parameters<typeof Table>[0];

interface DataType {
    nid?: React.Key
    fid?: string | number
    label?: string;
    icon?: string
    key?: string;
    children?: any[]
}
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;

const App: React.FC = () => {
    const [dataSource, setDataSource] = useState<DataType[]>([]);
    const [expandedRowKeys, setExpandedRowKeys]: any = useState([])
    const EditableCell: React.FC<EditableCellProps> = ({
        title,
        editable,
        children,
        dataIndex,
        record,
        handleSave,
        ...restProps
    }) => {
        const [editing, setEditing] = useState(false);
        const inputRef = useRef<InputRef>(null);
        const form = useContext(EditableContext)!;

        useEffect(() => {
            if (editing) {
                inputRef.current!.focus();
            }
        }, [editing]);

        const toggleEdit = () => {
            setEditing(!editing);
            form.setFieldsValue({ [dataIndex]: record[dataIndex] });
        };
        const save = async () => {
            try {
                const values = await form.validateFields();
                toggleEdit();
                handleSave({ ...record, ...values });
            } catch (errInfo) {
                console.log('Save failed:', errInfo);
            }
        };

        let childNode = children;

        if (editable) {
            childNode = editing ? (
                <Form.Item
                    style={{ margin: 0 }}
                    name={dataIndex}
                >
                    <Input ref={inputRef} onPressEnter={save} onBlur={save} />
                </Form.Item>
            ) : (
                <div className="editable-cell-value-wrap" style={{ paddingRight: 24 }} onClick={toggleEdit}>
                    {children}
                </div>
            );
        }

        return <td {...restProps}>{childNode}</td>;
    };
    useEffect(() => {
        getUserMenu()
    }, []);
    let ids: string[] = []
    const filterNav = (arr: any[]) => {
        for (const i in arr) {
            if (arr[i].children) {
                filterNav(arr[i].children)
                ids = [...ids, arr[i].nid]
            }
        }
    }
    const changeAll = () => {
        if (expandedRowKeys.length) {
            setExpandedRowKeys([])
            return
        }
        ids = []
        setDataSource(dataSource)
        filterNav(dataSource)
        setExpandedRowKeys(ids)
    }
    // 获取导航
    const getUserMenu = async (type = 0) => {
        const res = await getUserMenuList()
        setDataSource(res.data)
        ids = []
        if (type) return
        filterNav(res.data)
        setExpandedRowKeys(ids)
    }
    const onExpand = (expanded: boolean, record: any) => {
        if (expanded) { //展开
            setExpandedRowKeys([...expandedRowKeys, record.nid])
        } else {    //关闭
            const newSet = new Set(expandedRowKeys)
            newSet.delete(record.nid)
            setExpandedRowKeys(newSet)
        }
    }

    // 表头
    const defaultColumns: any = [
        {
            title: '导航名称',
            dataIndex: 'label',
            key: 'label',
            width: '30%',
            fixed: 'left',
            editable: true,
            render: (text: string) => {
                return <span>{text ? text : '/'}</span>
            }
        },
        {
            title: '图标索引',
            dataIndex: 'icon',
            key: 'icon',
            width: '20%',
            editable: true,
            render: (text: string) => {
                return <span>{text ? text : '/'}</span>
            }
        },
        {
            title: '导航路径',
            dataIndex: 'key',
            width: '30%',
            key: 'key',
            editable: true,
            render: (text: string) => {
                return <span>{text ? text : '/'}</span>
            }
        },
        {
            title: '操作',
            dataIndex: '',
            key: 'op',
            width: '20%',
            fixed: 'right',
            render: (record: any) => <div className='flex flex-ai-c'>
                <a onClick={handleAdd(record)}><PlusOutlined style={{ fontSize: '24px' }} title="添加下级" /></a>
                <a onClick={handleDelete(record)} style={{ margin: '0 20px' }}><DeleteOutlined style={{ fontSize: '24px', color: 'red' }} title="删除" /></a>
                {
                    record.children ? <div>
                        <Switch defaultChecked={record.expand ? true : false} checkedChildren='展开' unCheckedChildren='不展开' onChange={(checked) => changeSwitch(checked, record)} />
                    </div> : ''
                }

            </div>,
        },
    ];
    const changeSwitch = async (checked: boolean, item: any) => {
        console.log(checked, item)
        item.expand = checked ? 1 : 0
        await setUserMenuList(item)
    }
    const filter = (arr: any[], obj: any) => {
        for (const i in arr) {
            if (arr[i].nid == obj.nid) {
                arr[i] = { ...arr[i], ...obj }
            }
            if (arr[i].children) {
                filter(arr[i].children, obj)
            }

        }
        return arr
    }
    //删除
    const handleDelete = (record: any) => {
        return async () => {
            if (!record.id) {
                const newData = dataSource.filter((x: any) => x.id)
                setDataSource(newData)
                return
            }
            if (record.children) return message.info('不能删除父节点')

            const res = await delUserMenuList(record.nid)
            if (res.status == 200) {
                getUserMenu(1)
            }
        }
    };
    //保存
    const handleSave = async (row: DataType) => {
        const newArr = deepClone(dataSource)
        const arr = filter(newArr, row)
        if (row.label) await setUserMenuList(row)

        setDataSource(arr)
    };
    //添加
    const handleAdd = (record: any) => {
        return async () => {
            const { data } = await getNavigationId()
            setExpandedRowKeys([...expandedRowKeys, record.nid])
            if (record.children) {
                record.children.push({ nid: data, fid: record.nid })
            } else {
                record.children = [{ nid: data, fid: record.nid }]
            }
            const newArr = deepClone(dataSource)
            const arr = filter(newArr, record)
            setDataSource(arr)
        }
    };
    //添加根节点
    const handleAddRoot = async () => {
        const { data } = await getNavigationId()
        const addInfo = [...dataSource, { nid: data, fid: 0 }]
        setDataSource(addInfo)
    }
    const components = {
        body: {
            row: EditableRow,
            cell: EditableCell,
        },
    };

    const columns = defaultColumns.map((col: any) => {
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: (record: DataType) => ({
                record,
                editable: col.editable,
                dataIndex: col.dataIndex,
                title: col.title,
                handleSave,
            }),
        };
    });

    return (
        <div>
            <div className='flex flex-jc-sb' style={{ marginBottom: '20px' }}>
                <Button type='dashed' onClick={changeAll}>{expandedRowKeys.length ? '全部展开' : '全部收起'}</Button>
                <Button type='dashed' onClick={handleAddRoot}>添加根节点</Button>
            </div>
            <Table
                style={{ height: '77vh', overflow: 'auto' }}
                components={components}
                rowClassName={() => 'editable-row'}
                bordered
                rowKey="nid"
                expandable={{
                    expandedRowKeys: expandedRowKeys
                }}
                dataSource={dataSource}
                columns={columns as ColumnTypes}
                onExpand={onExpand}
                sticky
            />

        </div>
    );
};

export default App;